package org.elanfox.intellicommunity.intellicommunityadmin.base.security;

import lombok.Setter;
import org.elanfox.intellicommunity.intellicommunityadmin.base.exception.SmSessionException;
import org.elanfox.intellicommunity.intellicommunityadmin.base.exception.VerifyCodeException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.util.StringUtils;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * @author gmw
 * @date 2017-08-06
 */
@Setter
public class SmSecurityFailureHandler implements AuthenticationFailureHandler {
    private static final String USERNAME_NOT_FOUND = "该帐号不存在";
    private static final String BAD_CREDENTIALS_MSG = "用户名或者密码错误";
    private static final String USER_LOCKED = "该帐号已被锁定，请联系管理员";
    private final String failureUrl;
    private boolean forwardToDestination = false;
    private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

    public SmSecurityFailureHandler(String failureUrl) {
        this.failureUrl = failureUrl;
    }

    @Override
    public void onAuthenticationFailure(
            HttpServletRequest request,
            HttpServletResponse response,
            AuthenticationException exception) throws IOException, ServletException {
        if (StringUtils.isEmpty(failureUrl)) {
            throw new ServletException("failure url is required");
        }

        this.handleException(request, exception);
        if (this.forwardToDestination) {
            request.getRequestDispatcher(this.failureUrl).forward(request, response);
        } else {
            this.redirectStrategy.sendRedirect(request, response, this.failureUrl);
        }
    }

    private void handleException(HttpServletRequest request, AuthenticationException exception) {
        String msg;
        if (exception instanceof UsernameNotFoundException) {
            msg = USERNAME_NOT_FOUND;
        } else if (exception instanceof SmSessionException) {
            msg = exception.getMessage();
        } else if (exception instanceof VerifyCodeException) {
            msg = "验证码不正确";
        } else if (exception instanceof LockedException || exception instanceof DisabledException) {
            msg = USER_LOCKED;
        } else {
            msg = BAD_CREDENTIALS_MSG;
//            request.getSession().setAttribute(Constant.VERIFY_TAG, false);
        }
        if (forwardToDestination) {
            request.setAttribute("SPRING_SECURITY_LAST_EXCEPTION", msg);
        } else {
            HttpSession session = request.getSession(false);
            if (session != null) {
                request.getSession().setAttribute("SPRING_SECURITY_LAST_EXCEPTION", msg);
            }
        }
    }
}
